package com.hightop.axure.automic;

import io.appium.java_client.windows.WindowsDriver;
import lombok.extern.java.Log;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Point;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 主程序
 * @author xiehai
 * @date 2022/08/16 16:17
 */
@Log
public class Main {
    public static void main(String[] args) throws MalformedURLException {
        Logger.getGlobal().setLevel(Level.OFF);
        // axure可执行文件路径
        String axurePath = Environments.AXURE.getValue();
        // 杀死残留的axure进程
        try {
            // 通过配置路径解析Axure执行文件名称
            String axure = Paths.get(axurePath).getFileName().toString();
            Runtime.getRuntime().exec(String.format("taskkill /f /im %s", axure));
        } catch (Throwable ignore) {
        }
        DesiredCapabilities capabilities = new DesiredCapabilities();
        // 可执行文件路径
        capabilities.setCapability("app", axurePath);
        URL url = new URL(Environments.DRIVER_URL.getValue());
        String workspace = Environments.WORKSPACE.getValue();
        WindowsDriver<WebElement> driver = new WindowsDriver<>(url, capabilities);
        // 所有操作最多等待30分钟
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.MINUTES);
        WebDriver.Window window = driver.manage().window();
        // 根据分辨率设置
        window.setSize(new Dimension(1920, 1080));
        window.setPosition(new Point(0, 0));
        int exitCode = 0;
        try {
            Path root = Paths.get(workspace);
            // 打开并加载rp文件
            openAndLoadFile(driver, root, Environments.RP_FILE_NAME.getValue());
            // html文件转换
            publishHtml(driver, root.resolve("public"));
            log.info("rp文件转换成功");
        } catch (Exception e) {
            log.severe("rp文件转换失败");
            log.log(Level.SEVERE, e.getMessage(), e);
            exitCode = 1;
        } finally {
            // 关闭发布html打开的浏览器
            closeBrowser(url);
            // 关闭axure
            try {
                driver.close();
                Optional.ofNullable(AccessibilityIds.EXIT_NO_BTN.get(driver)).ifPresent(WebElement::click);
                driver.quit();
            } catch (Exception ignore) {
            }
            System.exit(exitCode);
        }
    }

    /**
     * try  * 加载rp文件
     * @param driver   {@link WindowsDriver}
     * @param filePath 文件存储路径
     * @param fileName 文件名
     */
    static void openAndLoadFile(WindowsDriver<WebElement> driver, Path filePath, String fileName) {
        // ctrl + o
        new Actions(driver).keyDown(Keys.CONTROL).sendKeys("o").keyUp(Keys.CONTROL).perform();
        // 选择文件
        WebElement element = AccessibilityIds.FILE_NAME.get(driver);
        element.click();
        element.sendKeys(filePath.resolve(fileName).toString());
        // 点击打开
        AccessibilityIds.FILE_OPEN_BTN.get(driver).click();
    }

    /**
     * 发布html
     * @param driver     {@link WindowsDriver}
     * @param targetPath 目标目录
     */
    static void publishHtml(WindowsDriver<WebElement> driver, Path targetPath) {
        // ctrl + shift + o
        new Actions(driver).keyDown(Keys.CONTROL).keyDown(Keys.SHIFT).sendKeys("o")
            .keyUp(Keys.CONTROL).keyUp(Keys.SHIFT).perform();
        WebElement publish = driver.findElementByName("Publish Project").findElement(By.className("DxDrawingControl"));
        // 发布目录选择
        new Actions(driver).moveToElement(publish).moveByOffset(104, -80).click().perform();
        AccessibilityIds.FOLDER_NAME.get(driver).sendKeys(targetPath.toString());
        // 点击选择目录
        AccessibilityIds.FILE_OPEN_BTN.get(driver).click();
        // 发布 可以直接使用enter快捷键
        new Actions(driver).sendKeys(publish, Keys.ENTER).perform();
        // 等待进度条消失
        try {
            WebElement process = AccessibilityIds.PUBLISH_PROCESS.get(driver);
            if (process.isDisplayed()) {
                new WebDriverWait(driver, TimeUnit.MINUTES.toSeconds(30L), 200)
                    .until(ExpectedConditions.invisibilityOf(process));
            }
        } catch (StaleElementReferenceException ignore) {
            // 忽略元素未能定位异常
        }
    }

    /**
     * 关闭打开的浏览器
     * @param url 驱动地址
     */
    static void closeBrowser(URL url) {
        DesiredCapabilities capabilities = new DesiredCapabilities();
        // 可执行文件路径
        capabilities.setCapability("app", Environments.BROWSER.getValue());
        try {
            WindowsDriver<WebElement> driver = new WindowsDriver<>(url, capabilities);
            TimeUnit.SECONDS.sleep(1);
            // 退出谷歌浏览器
            new Actions(driver)
                .keyDown(Keys.ALT).sendKeys("f").keyUp(Keys.ALT)
                .sendKeys("x")
                .perform();
        } catch (Exception ignore) {
            // 若退出浏览器失败 下次重新退出
        }
    }
}
